# project/adminx.py

import xadmin

from .models import Category,ServiceClass,Stage,Result,WorkFlow,WorkFlowLog
from .models import AddProject,ProjectList,WorkLoad,Opinion,ReportList,Postion,CodeClause,CodeList,Sz_Project
from xadmin import views
from xadmin.layout import Main, TabHolder, Tab, Fieldset, Row, Col, AppendedText, Side, Field


#xadmin中这里是继承object，不再是继承admin
# class EmailVerifyRecordAdmin(object):
#     # 显示的列
#     list_display = ['code', 'email', 'send_type', 'send_time']
#     # 搜索的字段
#     search_fields = ['code', 'email', 'send_type']
#     # 过滤
#     list_filter = ['code', 'email', 'send_type', 'send_time']


# class BannerAdmin(object):
#     list_display = ['title', 'image', 'url','index', 'add_time']
#     search_fields = ['title', 'image', 'url','index']
#     list_filter = ['title', 'image', 'url','index', 'add_time']

class CategoryAdmin(object):
    list_display = ['name', 'desc', 'is_root','parent','is_abort','sort','get_WorkFlow_nums']
    search_fields = ['name', 'desc', 'is_root','parent','is_abort','sort']
    list_filter = ['name', 'desc', 'is_root','parent','is_abort','sort']
    ordering = ['sort']
    model_icon = 'fa fa-cog'
xadmin.site.register(Category,CategoryAdmin)

class ServiceClassAdmin(object):
    list_display = ['name', 'desc', 'is_root','parent','is_abort','sort']
    search_fields = ['name', 'desc', 'is_root','parent','is_abort','sort']
    list_filter = ['name', 'desc', 'is_root','parent','is_abort','sort']
xadmin.site.register(ServiceClass,ServiceClassAdmin)

class StageAdmin(object):
    list_display = ['name', 'desc', 'sort']
    search_fields = ['name', 'desc', 'sort']
    list_filter = ['name', 'desc', 'sort']
xadmin.site.register(Stage,StageAdmin)

class ResultAdmin(object):
    list_display = ['name', 'sort']
    search_fields = ['name', 'sort']
    list_filter = ['name', 'sort']
xadmin.site.register(Result,ResultAdmin)

class WorkFlowAdmin(object):
    list_display = ['name', 'sort']
    search_fields = ['name', 'sort']
    list_filter = ['name', 'sort']
    # 下拉选择过多时，通过外键的主表添加字段，异步搜索呈现内容
    # relfield_style = 'fk-ajax
    # 列表中字段直接修改
    list_editable = ['name']
xadmin.site.register(WorkFlow,WorkFlowAdmin)

class WorkFlowLogAdmin(object):
    list_display = ['name', 'desc']
    search_fields = ['name', 'desc']
    list_filter = ['name', 'desc']
xadmin.site.register(WorkFlowLog,WorkFlowLogAdmin)

class AddProjectAdmin(object):
    list_display = ['id','project_list_col', 'contract_list_col','add_no','company','operator','isContract_col','isDo','addtime']
    # raw_id_fields = ['serviceclass',] 
    search_fields = ['tempname', 'company__fullname','operator__nick_name','projects__projectname']
    list_filter = ['serviceclass','company','operator__nick_name']
    filter_horizontal = ['serviceclass__name']
    wizard_form_list = [
        ("基本信息", ("tempname", "category",'serviceclass','company','contacter')),
        ("其它信息", ("operator", "status", "isSign",'isDo'))
    ]
    list_editable = ['add_no','isDo']
    relfield_style = 'fk-ajax'
    # form_layout = (
    #             Fieldset(
    #                      Row('tempname', 'company'),  # Row 表示将里面的字段作为一行显示
    #                      Row('category','serviceclass'),
    #                      ),
    #             Fieldset(
    #                      Row('contacter','operator'),
    #                      Row('workload','monovalent','total'),
    #                      Row('status','isSign','isDo'),
    #                      Row('desc'),
    #                      ),
    #             )
    '''
    readonly_fields = ('cservice',)指定一些字段为只读，不可修改
    list_filter = [] #过滤器
    date_hierarchy =['publication_date']  #添加过滤（这里是过滤日期）
    ordering = ['-publication_date',]   #排序（这里以日期排序，加‘-’表示降序）
    filter_horizontal = ('authors',) #filter_horizontal 从‘多选框’的形式改变为‘过滤器’的方式，水平排列过滤器，必须是一个 ManyToManyField类型，且不能用于 ForeignKey字段，默认地，管理工具使用`` 下拉框`` 来展现`` 外键`` 字段
    filter_vertical = ['authors',]#同上filter_horizontal，垂直排列过滤器
    raw_id_fields = ['publisher',] #将ForeignKey字段从‘下拉框’改变为‘文本框’显示
    list_editable = ['csdevice'] #在列表页可直接编辑的字段
    model_icon = 'fa fa-user-secret'  #图标样式
    style_fields = {'csdevice': 'm2m_transfer','csservice': 'ueditor',} #字段显示样式
    style_fields = {'subjects': 'checkbox-inline', }#设置为内联复选框
    refresh_times = [10, 60] #自动刷新时间
    show_detail_fields=['ttdsn'] #在指定的字段后添加一个显示数据详情的一个按钮
    relfield_style = 'fk-ajax' #涉及到外键下拉的时候使用ajax搜索的方式而不是全部列出的方式，比如在分类下拉很多的情况下，这个功能就很好用
    free_query_filter=['字段1','字段2',......]#默认为 True , 指定是否可以自由搜索. 如果开启自由搜索, 用户可以通过 url 参数来进行特定的搜索
    exclude=['字段1','字段2',......]#隐藏字段
    is_execute = True  # 使用js插件
    #  列聚合，可用的值："count","min","max","avg",  "sum",在list表格下面会增加一行统计的数据
    aggregate_fields = {"id": "max"}   # 显示统计数据  统计id字段最大的值
    # 添加数据时候，一步一步提供数据，分块显示
    wizard_form_list = [
            ("基础信息", ("name", "contact", "telphone", "address")),
            ("其它信息", ("customer_id", "expire", "description")),
        ]
    grid_layouts = ("table", "thumbnails") #列表的布局方式，是以表格一行一条的方式还是类似于缩略图的方式展示的
    list_per_page = 50 # 每页显示数据的条数
    list_max_show_all = 200 #每页最大显示数据的条数
    #模板修改
    #form_template = 'card_pool/form.html'
    add_form_template = 'card_pool/form.html'
    change_form_template = 'card_pool/form.html'
    fieldsets          ，详细页面时，使用fieldsets标签对数据进行分割显示
    empty_value_display = "列数据为空时，显示默认值"

    # 显示还原按钮，删除修改的信息可以还原
    reversion_enable = True
    list_per_page = 20   每页显示20个
    actions = ('ocr_action', 'excel_action', 'auto_excel_action') 在类中自定义的函数方法
    auto_excel_action.short_description='自动化导入数据文件'         函数名描述

    object_list_template = "test.html"   自定义页面

    data_charts          图表，该属性为dict类型，key为图表的标示名称，value为图表的具体设置属性
    data_charts = {
            "user_count": {'title': u"约运动",
                        "x-field": "sport_time", 
                        "y-field": ("people_nums",),
                        },
        }

    图表属性：

　　title :   图表的显示名称
　　x-field : 图表的 X 轴数据列, 一般是日期, 时间等
　　y-field : 图表的 Y 轴数据列, 该项是一个 list, 可以同时设定多个列, 这样多个列的数据会在同一个图表中显示
    '''
    # style_fields = {"status": ""} #设定字段的显示样式：checkbox-inline,多选竖排；radio-inline单选竖排
    # Xadmin导入excel数据及再加工数据和优化预览记录的总结
    # https://blog.csdn.net/hawk_2016/article/details/89182373

    # 过滤当前用户数据
    # def get_queryset(self):
    #   return UpdateTinker.objects.filter(user=self.request.user)
    '''
    '''
    # 禁止页面批量删除,重写虚拟环境根目录下\Lib\site-packages\xadmin\views\edit.py中的has_delete_permission方法
    # def has_delete_permission(self,*args,**kwargs):
    #     if args:
    #         return True
    #     return False
	
	# # 自动添加管理员,重写虚拟环境根目录下\Lib\site-packages\xadmin\views\edit.py中的save_models方法
    # def save_models(self):
    #     self.new_obj.user = self.request.user
    #     super().save_models()
    
    # # 设置用户只能查看自己填写的数据
    # def queryset(self):
    #     qs = super(UserManageAdmin, self).queryset()
    #     if self.request.user.is_superuser:  # 超级用户可查看所有数据
    #         return qs
    #     else:
    #         que = qs.filter(user=self.request.user)
    #         return que 
    '''
    多参数使用
class UpdatesTinkerFilter(FilterSet):
    """
    商品的过滤filter
    """
    applicationId = filters.CharFilter(name="applicationId", lookup_expr='iexact')
    version = filters.CharFilter(name="version", lookup_expr='iexact')

    class Meta:
        model = UpdateTinker
        fields = ['applicationId', 'version']

class UpdatesTinkerViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    """
    Tinker 热更新列表
    """
    queryset = UpdateTinker.objects.all()
    serializer_class = UpdatesSerializer
    pagination_class = UpdatesTinkerPagination
    filter_backends = (DjangoFilterBackend,)
    search_fields = ('applicationId', 'version')
    # 查找过滤class
    filter_class = UpdatesTinkerFilter
    # 默认搜索 tinkerId
    lookup_field = "tinkerId"
    
        Serializer 常用设置
        自定义过滤
        设置自读
        过滤 字段validate

    def validate_name(self, value):
        """
        Check that the blog post is about Django.
        """
        if 'django' not in value.lower():
            raise serializers.ValidationError("Blog post is not about Django")
        return value

    class Meta:
        model = Package
        fields = "__all__"
        # extra_kwargs = {
        #     'sectionName': {'required': False},
        #     'client': {'required': False},
        #     'applicationID': {'required': False},
        # }
        # read_only_fields = ("name",)

    class ModelFormAdminView(ModelAdminView):#完整的模板
        form = forms.ModelForm
        formfield_overrides = {}
        readonly_fields = ()
        style_fields = {}
        exclude = None
        relfield_style = None
        save_as = False
        save_on_top = False
        add_form_template = None
        change_form_template = None

    # 表单根据用户显示不同的字段内容
    def get_model_form(self, **kwargs):
        if self.org_obj is None:
            self.fields = ['username', 'mobile', 'is_staff']
         return super().get_model_form(**kwargs)

    # 可分为Main主区域和Side侧边区域，Main或Side中又可通过Fieldset再分多个区域。
    # Fieldset为一个元组，第一个字段为需要设置的名称，其它字段均为模型中的字段名
    form_layout = (
    Main(
        Fieldset('基础信息',
                 'site', 'device_name', 'device_id', 'device_type', 'account', 'password'),
        Fieldset('EXTRA',
                 'device_model', 'supplier', 'responsible_by', 'device_ip', 'sn_number'),
    ),
    Side(
        Fieldset('其它',
                 'buy_date', 'expire_date', 'note', 'attachment', 'date'),
    )
)

    # 有时模型中会需要记录添加数据的用户，保存在created_by这样的字段中。这时我们就需要重写save_model方法，在保存模型时存入用户的信息。
    def save_models(self):
        obj = self.new_obj
        self.new_obj.area_company = Group.objects.get(user=self.request.user)
        super().save_models()

    def queryset(self):
        """函数作用：使当前登录的用户只能看到自己负责的设备"""
        qs = super(DeviceAdmin, self).queryset()
        if self.request.user.is_superuser:
            return qs
        return qs.filter(area_company=Group.objects.get(user=self.request.user))

    # 将site字段添加到autocomplete_fields（autocomplete_fields作用是下拉选项会多出一个搜索框，方便搜索选择）之后，会自动进行过滤，满足上述场景要求。
    # 如果不使用autocomplete_fields，可以通过重写formfield_for_foreignkey方法去做筛选。如下：
    def formfield_for_dbfield(self, db_field, **kwargs):
        if not self.request.user.is_superuser:
            if db_field.name == "site":
                 kwargs["queryset"] = Site.objects.filter(area_company=Group.objects.get(user=self.request.user))
        return super(DeviceAdmin, self).formfield_for_dbfield(db_field, **kwargs)

    # 自定义一个显示字段(get_goods)，该字段必须为只读（readonly_fields）才会显示出来
    def get_goods(self,obj):
        goods_queryset = obj.ordergoods_set.all()
        return  str(["商品%s:%s 单价:%s 元"%(i.goods.id,i.goods.name,i.goods.price) for i in goods_queryset])
    get_goods.short_description = '购买的商品'
 
    list_display = ['order_id','user','status','get_goods']
    readonly_fields = ("order_id",'get_goods')

    # 后台用save_models和delete_model修改模型类后就会执行改函数
    def save_models(self):
    # 新的对象
    obj = self.new_obj
    # 可以在这里面写些逻辑
    # 保存该对象
    obj.save()

    def delete_model(self):
        # 删除数据对象
        obj = self.obj
        # 相应的操作
        obj.delete()

    # 想对某些字段设置颜色，可用下面的设置
    from django.db import models
    from django.contrib import admin
    from django.utils.html import format_html
    
    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
        color_code = models.CharField(max_length=6)
    
        def colored_name(self):
            return format_html(
                '<span style="color: #{};">{} {}</span>',
                self.color_code,
                self.first_name,
                self.last_name,
            )
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('first_name', 'last_name', 'colored_name')

    #增加页面显示的列 ‘跳转’——显示自定义的html代码
    def go_to(self):
        from django.utils.safestring import mark_safe
        #mark_safe后就不会转义
        return mark_safe("<a href='https://home.cnblogs.com/u/derek1184405959/'>跳转</a>")
    go_to.short_description = "跳转"


    设置xadmin新用户主页的默认布局
    # xadmin/model.py
    @python_2_unicode_compatible
    class UserSettings(models.Model):
        user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_(u"user"))
        key = models.CharField(_('Settings Key'), max_length=256)
        value = models.TextField(_('Settings Content'))
        
        # 重写save方法
        def save(self, force_insert=False, force_update=False, using=None,
                update_fields=None):

            if not self.value:
                self.value = "|"
                super(UserSettings, self).save()
                page_id = 'home'
                default_list = [
                    [{'list': '{"title": "", "model": "auth.user"}'}, ],
                    [{'list': '{"title": "", "model": "cashflows.bank_cash_flows"}'}, ],
                    [{'html': '{"title": "Test Widget", "content": "第一次测试！！"}'}, ],
                    [{'qbutton': '{"title": "aaa"}'}, ],
                ]
                
                for i in default_list:
                    user_widget = UserWidget()
                    for j in i:
                        for z in j.keys():
                            user_widget.page_id = page_id
                            user_widget.user_id = self.user_id
                            user_widget.widget_type = z
                            user_widget.value = j[z]
                            user_widget.save()
                
                id_list = []  # 存放user的id
                a = UserWidget.objects.filter(user_id=self.user)
                for i in a:
                    id_list.append(i.id)

                self.value = "%s,%s|%s,%s" % (id_list[0], id_list[1], id_list[2], id_list[3])
                
                UserSettings.objects.filter(user_id=self.user).value = self.value
                super(UserSettings, self).save()
            else:
                super(UserSettings, self).save()

    #可以通过下面进行自定义显示页面。
    class Test(models.Model):

        class Meta:
            verbose_name = u"自定义页面"
            verbose_name_plural = verbose_name

        def __unicode__(self):
            return self.Meta.verbose_name

    class TestAdmin(object):
        list_display = []
        object_list_template = "test.html"


    '''
    style_fields = {'serviceclass': 'checkbox-inline', }
xadmin.site.register(AddProject,AddProjectAdmin)

class ProjectListAdmin(object):
    list_display = ['projectname','projectno','resultclass','stage','completer','status','p_starttime','p_overtime','p_approvetime','userOperate','get_conpany']
    list_editable = ['projectno','completer','resultclass','sz_get_no','stage','status','isarchive','p_archivetime','ischeckout','p_checkouttime']
    search_fields = ['projectname','completer__nick_name','projectno']
    exclude = ['userOperate']
    list_filter = ['resultclass','addproject__company__fullname','status','p_approvetime','addproject__category__name','stage']
    filter_horizontal = []
    relfield_style = 'fk-ajax'
    # list_filter = ['name', 'projectno','projectleader','completer','status']
    # def queryset(self):
    #     """函数作用：使当前登录的用户只能看到自己的数据"""
    #     qs = super(ProjectListAdmin, self).queryset()
    #     if self.request.user.is_superuser:
    #         return qs
    #     return qs.filter(completer=self.request.user)
xadmin.site.register(ProjectList,ProjectListAdmin)

class Sz_ProjectAdmin(object):
    # 设置queryset返回我们需要的对象列表 而不是所有的对象列表
    list_display = ['projectname','projectno','sz_get_no','resultclass','stage','completer','status','p_finishtime','userOperate']
    list_editable = ['projectno','completer','resultclass','sz_get_no','stage','status','isarchive','p_archivetime','ischeckout','p_checkouttime']
    search_fields = ['projectname','completer__nick_name','sz_get_no']
    exclude = ['userOperate']
    list_filter = ['resultclass','addproject__company__fullname',]
    def queryset(self):
        # 调用父类的方法
        qs = super(Sz_ProjectAdmin, self).queryset()
        # 指定只显示市政院项目pk=45
        qs = qs.filter(addproject__company__pk=45)
        return qs
xadmin.site.register(Sz_Project,Sz_ProjectAdmin)

class PostionAdmin(object):
    list_display = ['project','piont','desc']
    search_fields = ['project','piont','desc']
xadmin.site.register(Postion,PostionAdmin)

class WorkLoadAdmin(object):
    list_display = ['projectname', 'holes','totals','add_by']
    # search_fields = ['resultname', 'worktype','survey','size']
    # list_filter = ['resultname', 'worktype','survey','size']
xadmin.site.register(WorkLoad,WorkLoadAdmin)

class OpinionAdmin(object):
    list_display = ['projectname', 'flow','content','examiner','addtime']
    search_fields = ['projectname__projectname']
    list_filter = ['examiner', 'flow']
    ordering = ['-addtime',]
xadmin.site.register(Opinion,OpinionAdmin)

class ReportListAdmin(object):
    list_display = ['projectname', 'partname','tankser','tankstime','reporter','reporttime']
    search_fields = ['projectname__projectname','partname']
    style_fields = {"desc": "ueditor"}#声明ueditor变量
    relfield_style = 'fk-ajax'
    # list_filter = ['projectname', 'resultname','partname','elevation0','designedelevation','depth','starttime','completer']
    # wizard_form_list = [
    #     ("基本信息", ("projectname", "partname",'teststarttime','testendtime','receiver','incometype','amount','payedtime','isinvoice')),
    #     ("其它信息", ('iscar','worker',"tankser",'tankstime',"reporter", "reporttime"))
    # ]
    readonly_fields = ['addtime','update_time']

xadmin.site.register(ReportList,ReportListAdmin)

class CodeListAdmin(object):
    list_display = ['codename','edition','category','serviceClass','isactive','action_time','url','add_by']
    search_fields = ['codename','edition']
    exclude = ['add_by']
    def save_models(self):
        self.new_obj.add_by = self.request.user
        super().save_models()
xadmin.site.register(CodeList,CodeListAdmin)

class CodeClauseAdmin(object):
    list_display = ['codeid','sort','no','clause','remark','add_by']
    exclude = ['add_by']
    search_fields = ['clause','clause','sort']
    def save_models(self):
        self.new_obj.add_by = self.request.user
        super().save_models()
xadmin.site.register(CodeClause,CodeClauseAdmin)